#pragma once

#include <iostream> 
#include <cassert>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <string>
#include <cstdlib>
#include <cerrno>
#include <cstring>
#include <sys/shm.h>
using namespace std;
#define PATH_NAME "."
#define PROJECT_ID 0x66
#define SIZE 4096 //比较合理,效率高


key_t getkey(const string& path)
{
    key_t k = ftok(path.c_str(),PROJECT_ID);
    if(k == -1)
    {
        cerr<<errno<<strerror(errno)<<endl;
        exit(-1);
    }
    return k;
}
int shm_helper(key_t k,int flag)
{
    int shmid = shmget(k,SIZE,flag);
    if(shmid == -1)
    {
        //错误
        cerr<<errno<<strerror(errno)<<endl;
        exit(-1);
    }
    return shmid;
}

int creatshm(key_t k)
{
    return shm_helper(k,IPC_CREAT | IPC_EXCL | 0600);
}

int getshm(key_t k)
{
    return shm_helper(k,IPC_CREAT);
}

void* shmattach(int shmid)
{
    void* mem = shmat(shmid,nullptr,0);
    if((long long)mem == -1)
    {
        cerr<<errno<<strerror(errno)<<endl;
        exit(-1);
    }
    return mem;
}

void detachshm(const void* addr)
{
    int n = shmdt(addr);
    if(n == -1)
    {
        cerr<<errno<<strerror(errno)<<endl;
        exit(-1);
    }
}

void delshm(int shmid)
{
    if(shmctl(shmid,IPC_RMID,nullptr) == -1)
    {
        cerr<<errno<<strerror(errno)<<endl;
        exit(-1);
    }
}


